﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Soundteller.Common.Tests;
using Soundteller.Visual.Model;
using Soundteller.Visual.Model.Interfaces;
using Soundteller.Visual.Repositories;
using Soundteller.Visual.Repositories.Interfaces;

namespace Soundteller.Visual.Tests.Unit.Repositories.GraphicBufferRepositorySpecifications
{
    public abstract class WhenPush : TestBase
    {
        protected IGraphicBufferRepository GraphicBufferRepository { get; private set; }
        protected Mock<IMemoryContext> MemoryContext { get; private set; }
        protected abstract GraphicBase GraphicToAdd { get; }

        protected override void Arrange()
        {
            MemoryContext = new Mock<IMemoryContext>();
            MemoryContext.Setup(c => c.GraphicBuffer).Returns(new Stack<GraphicBase>());

            GraphicBufferRepository = new GraphicBufferRepository(MemoryContext.Object);
        }

        protected override void Act()
        {
            GraphicBufferRepository.Push(GraphicToAdd);
        }
    }

    [TestClass]
    public class WhenPushGivenEmptyGraphic : WhenPush
    {
        protected override GraphicBase GraphicToAdd
        {
            get { return null; }
        }

        protected override void Act()
        {
            ExpectException(() => base.Act());
        }

        [TestMethod]
        public void ThenAnArgumentNullExceptionShouldBeThrown()
        {
            Exception.VerifyArgumentNullException("graphic");
        }
    }

    [TestClass]
    public class WhenPushGivenEmptyBuffer : WhenPush
    {
        private GraphicBase _graphicToAdd;
        private GraphicBase _addedGraphic;

        protected override GraphicBase GraphicToAdd
        {
            get
            {
                if (_graphicToAdd == null) _graphicToAdd = new GeneratedGraphic { Name = "unit-test" };

                return _graphicToAdd;
            }
        }

        protected override void Act()
        {
            base.Act();
            _addedGraphic = GraphicBufferRepository.Pop();
        }

        [TestMethod]
        public void ThenPopShouldReturnAddedGraphic()
        {
            Assert.AreEqual(_graphicToAdd, _addedGraphic);
        }
    }
}
